package testJdk.thread.pool.testThreadPool;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * 线程池：让外界提交任务，对内则是执行任务
 * 值得注意的是，这个线程池不持有线程，只是创造最多4个线程，把任务交给这些线程去执行
 * 这四个线程共享同一个taskList，他们的run方法里面有while循环，只要taskList中有task，就一直执行
 *
 */
public class MyThreadPool {
    private final Logger logger = LoggerFactory.getLogger(MyThreadPool.class);

    /**
     * 任务队列：线程安全的集合
     */
    private final List<Runnable> taskList = Collections.synchronizedList(new LinkedList<>());
    /**
     * 执行的任务数量（总数）
     */
    private int num;

    /**
     * 核心线程数量
     */
    private final int corePoolSize;

    /**
     * 最大线程数量
     */
    private final int maxPoolSize;

    /**
     * 任务队列长度，由构造决定
     */
    private final int workerSizeLimit;

    public MyThreadPool(int corePoolSize, int maxSize, int workerSize) {
        this.corePoolSize = corePoolSize;
        this.maxPoolSize = maxSize;
        this.workerSizeLimit = workerSize;
    }

    /**
     * 提交任务：将任务添加到集合中，需要判断是否超出了集合总长度
     *
     * @param task 任务
     */
    public void submit(Runnable task) {
        if (taskList.size() >= workerSizeLimit) {
            logger.info("任务{}被丢弃了", task);
        } else {
            // 执行任务
            execTask(task);
        }
    }

    /**
     * 执行任务：判断当前任务数量，决定创建核心线程还是非核心线程
     *
     * @param task 任务
     */
    private void execTask(Runnable task) {
        taskList.add(task);

        if (num < corePoolSize) {
            new MyWorker("核心线程：" + num, taskList).start();
            num++;
        } else if (num < maxPoolSize) {
            new MyWorker("非核心线程：" + num, taskList).start();
            num++;
        } else {
            logger.info("任务{}被缓存了。。。", task);
        }
    }
}
